package com.speily.current;

import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Auther: SPL
 * @Date: 2019-08-05 13:23
 * @Description: - 倒计时器 CountDownLatch 可以实现 join 相同的功能，但是更加的灵活。
 */
public class CountDownLatchTest implements Runnable{

//    CountDownLatch(int count) //实例化一个倒计数器，count指定计数个数
//    countDown() // 计数减一
//    await() //等待，当计数减到0时，所有线程并行执行


//    生成了一个CountDownLatch实例。
//    计数数量为5，这表示需要有5个线程来完成任务，等待在CountDownLatch上的线程才能继续执行。
//            latch.countDown();方法作用是通知CountDownLatch有一个线程已经准备完毕，倒计数器可以减一了。
//            latch.await()方法要求主线程等待所有10个检查任务全部准备好才一起并行执行。


    static final CountDownLatch latch = new CountDownLatch(5);
    static final CountDownLatchTest demo = new CountDownLatchTest();

    @Override
    public void run() {
        // 模拟检查任务
        try {
            Thread.sleep(new Random().nextInt(10) * 1000);
            System.out.println("check complete");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //计数减一
            //放在finally避免任务执行过程出现异常，导致countDown()不能被执行
            latch.countDown();
        }
    }


    public static void main(String[] args) throws InterruptedException {
        ExecutorService exec = Executors.newFixedThreadPool(5);
        for (int i=0; i<5; i++){
            exec.submit(demo);
        }

        // 等待检查
        latch.await();

        // 发射
        System.out.println("Fire!");
        // 关闭线程池
        exec.shutdown();
    }

}
